package com.ease.job.quartz.service.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.ease.job.quartz.service.CronJobManagementService;
import com.ease.job.quartz.vo.JobDetailObject;
import com.ease.job.quartz.vo.JobGroupObject;
import com.ease.job.quartz.vo.TriggerObject;
import com.ease.platform.access.service.impl.AbstractNamespaceJdbcTemplateAccessServiceImpl;

/**
 * SQL> desc QRTZ_JOB_DETAILS; Name Type Nullable Default Comments ----------------- ------------- -------- -------
 * -------- JOB_NAME VARCHAR2(200) JOB_GROUP VARCHAR2(200) DESCRIPTION VARCHAR2(250) Y JOB_CLASS_NAME VARCHAR2(250)
 * IS_DURABLE VARCHAR2(1) IS_VOLATILE VARCHAR2(1) IS_STATEFUL VARCHAR2(1) REQUESTS_RECOVERY VARCHAR2(1) JOB_DATA BLOB Y
 *
 * SQL> desc QRTZ_TRIGGERS; Name Type Nullable Default Comments -------------- ------------- -------- ------- --------
 * TRIGGER_NAME VARCHAR2(200) TRIGGER_GROUP VARCHAR2(200) JOB_NAME VARCHAR2(200) JOB_GROUP VARCHAR2(200) IS_VOLATILE
 * VARCHAR2(1) DESCRIPTION VARCHAR2(250) Y NEXT_FIRE_TIME NUMBER(13) Y PREV_FIRE_TIME NUMBER(13) Y PRIORITY NUMBER(13) Y
 * TRIGGER_STATE VARCHAR2(16) TRIGGER_TYPE VARCHAR2(8) START_TIME NUMBER(13) END_TIME NUMBER(13) Y CALENDAR_NAME
 * VARCHAR2(200) Y MISFIRE_INSTR NUMBER(2) Y JOB_DATA BLOB Y
 */
public class CronJobManagementServiceImpl extends AbstractNamespaceJdbcTemplateAccessServiceImpl implements CronJobManagementService, ApplicationContextAware {

	private ApplicationContext applicationContext;

	static class Statement {
		static String findAllJobDetails = "SELECT * FROM QRTZ_JOB_DETAILS JD, QRTZ_TRIGGERS TI WHERE JD.JOB_NAME =TI.JOB_NAME AND JD.JOB_GROUP=TI.JOB_GROUP ORDER BY TI.START_TIME";
	}

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	public List<Map<String, Object>> findAllJobDetails() {

		return this.getJdbcTemplateDataAccessObject().find(Statement.findAllJobDetails, new RowMapper<Map<String, Object>>() {

			public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {

				return null;
			}

		});

	}

	public List<JobGroupObject> findJobGroupObjects() {

		try {
			String[] schedulerFactoryBeanNames = applicationContext.getBeanNamesForType(org.springframework.scheduling.quartz.SchedulerFactoryBean.class);
			if (null != schedulerFactoryBeanNames) {
				List<JobGroupObject> jobGroupObjects = new ArrayList<JobGroupObject>();

				for (String schedulerFactoryBeanName : schedulerFactoryBeanNames) {
					SchedulerFactoryBean schedulerFactoryBean = (SchedulerFactoryBean) applicationContext.getBean(schedulerFactoryBeanName);
					Scheduler scheduler = schedulerFactoryBean.getScheduler();
					String[] jobGroupNames = scheduler.getJobGroupNames();
					if (null != jobGroupNames) {
						for (String jobGroupName : jobGroupNames) {
							JobGroupObject jobGroupObject = new JobGroupObject();
							jobGroupObjects.add(jobGroupObject);

							jobGroupObject.setName(jobGroupName);
							String[] jobNames = scheduler.getJobNames(jobGroupName);

							if (null != jobNames) {
								List<JobDetailObject> jobDetailObjects = new ArrayList<JobDetailObject>();
								jobGroupObject.setJobDetailObjects(jobDetailObjects);
								for (String jobName : jobNames) {
									JobDetail jobDetail = scheduler.getJobDetail(jobName, jobGroupName);
									JobDetailObject jobDetailObject = new JobDetailObject();
									jobDetailObjects.add(jobDetailObject);
									jobDetailObject.setJobDetail(jobDetail);
									Trigger[] triggers = scheduler.getTriggersOfJob(jobName, jobGroupName);

									if (null != triggers) {
										List<TriggerObject> triggerObjects = new ArrayList<TriggerObject>();
										jobDetailObject.setTriggerObjects(triggerObjects);
										for (Trigger trigger : triggers) {
											TriggerObject triggerObject = new TriggerObject();
											triggerObjects.add(triggerObject);
											triggerObject.setTrigger(trigger);
											triggerObject.setState(scheduler.getTriggerState(trigger.getName(), jobGroupName));
										}
									}
								}
							}
						}
					}

				}
				return jobGroupObjects;
			}
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
